package com.ems.controller;

import com.ems.config.LogPointer;
import com.ems.service.ICameraService;
import com.ems.util.FFMpegUtil;
import com.ems.util.HttpUtils;
import com.ems.vo.BaseResult;
import com.ems.vo.CameraVo;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;

/**
 * <p>
 * 摄像头 前端控制器
 * </p>
 * @author WuZH
 * @since 2023-11-08
 */
@RestController
@RequestMapping ("/camera")
@CrossOrigin (value = "*", maxAge = 3600)
public class CameraController {

    @Resource
    private ICameraService iCameraService;


    /**
     * 加载相机列表，并组装前端获取视频直播流地址
     * http://ip:port/live?port=1935&app=live&stream=cameraName
     * ip：nginx中配置的http请求地址
     * port：nginx中配置的http请求端口
     * live：nginx中配置的location子地址
     * port=1935：nginx中配置rtmp的应用端口
     * app=live：nginx中配置rtmp的应用名称
     * stream=cameraName：ffmpeg启动时指定的相机标识符
     * @param cameraVo
     * @return
     */
    @RequestMapping ("queryList")
    @LogPointer ("相机列表")
    public BaseResult queryList (@RequestBody CameraVo cameraVo) {
        List<CameraVo> cameraVos = iCameraService.queryList ( cameraVo );
        for ( CameraVo vo : cameraVos ) {
            vo.setCameraUrl ( FFMpegUtil.getHttpStr ( vo.getCameraCode () ) );
            boolean online = HttpUtils.isOnline ( vo.getCameraIp () );
            if ( online ) {
                vo.setStatus ( 1 );
            } else {
                vo.setStatus ( 0 );
            }
        }
        return BaseResult.success ( cameraVos, iCameraService.queryCount ( cameraVo ) );
    }


    /**
     * 保存相机
     * 1、确保相机编码cameraCode的唯一性，该字段也是确保系统中所有相机的唯一性
     * 命名规则：商户_相机编号
     * @param cameraVo
     * @return
     */
    @RequestMapping ("saveSingle")
    @LogPointer ("保存相机")
    public BaseResult saveSingle (@RequestBody CameraVo cameraVo) {
        cameraVo = iCameraService.saveSingle ( cameraVo );
        return BaseResult.success ( cameraVo );
    }

    /**
     * 重新刷新摄像头
     * 1、关闭ffmpeg进程
     * 2、重新加载推流命令
     * @return
     */
    @RequestMapping ("refresh")
    @LogPointer ("刷新摄像头，重新推流")
    public BaseResult refresh (@RequestBody CameraVo cameraVo) {
        cameraVo = iCameraService.querySingle ( cameraVo );
        iCameraService.kill ( cameraVo.getCameraCode () );
        // 检查摄像头是否在线
        boolean online = HttpUtils.isOnline ( cameraVo.getCameraIp () );
        if ( ! online ) {
            return BaseResult.fail ( "999998", "设备不在线" );
        }
        // ffmpeg 推流命令
        String command = FFMpegUtil.cmdFlow ( cameraVo.getCameraUser (), cameraVo.getCameraPassword (), cameraVo.getCameraIp (), cameraVo.getCameraPort (), cameraVo.getCameraCode () );
        FFMpegUtil.getCmdFlowProcess ( command, cameraVo.getCameraCode (), cameraVo.getCameraIp () );
        return BaseResult.success ();
    }


    public static void main (String[] args) {
        boolean online = HttpUtils.isOnline ( "192.168.1.64" );
        System.out.println ( online );
        try {
            // 调用CMD命令
            ProcessBuilder processBuilder = new ProcessBuilder ( "cmd.exe", "/c", "ffmpeg -re  -rtsp_transport tcp -i \"rtsp://admin:1qa2ws3ed@192.168.1.64:554/h264/ch33/main/av_stream?transportmode=unicast\" -f flv -vcodec h264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 640*360 -q 10 \"rtmp://localhost:1935/live/chaohu_camera_1\"" ); // /c参数表示执行后关闭CMD窗口
            processBuilder.redirectErrorStream ( true ); // 将错误输出流与标准输出流合并
            Process process = processBuilder.start ();

            // 获取命令输出结果
            InputStream inputStream = process.getInputStream ();
            BufferedReader reader = new BufferedReader ( new InputStreamReader ( inputStream, "GBK" ) ); // 设置编码为GBK
            String line;
            while ( ( line = reader.readLine () ) != null ) {
                System.out.println ( line );
            }
            // 等待命令执行完成
            process.waitFor ();
        } catch ( IOException | InterruptedException e ) {
            e.printStackTrace ();
        }
    }

}
